#include <iostream>
#include <string>
#include <ctime>
#include <cassert>
#include <unistd.h>
#include "Protocol.hpp"
#include "Socket.hpp"

enum
{
    CONNECT_ERR = 1
};

void manual(char *argv)
{
    std::cout << argv << " ip port" << std::endl;
}

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        manual(argv[0]);
        exit(1);
    }
    // 服务器网络结构体
    St st;
    st.Socket();
    bool r = st.Connect(argv[1], argv[2]);
    if (r == false)
    {
        lg(FATAL, "connect failed! %d:%s", errno, strerror(errno));
        exit(CONNECT_ERR);
    }
    srand(time(nullptr) ^ getpid());
    int cnt = 1;
    const std::string opers = "+-*/%=-=&^";

    std::string inbuffer_stream;
    while (cnt <= 10)
    {
        std::cout << "===============第" << cnt << "次测试....., " << "===============" << std::endl;
        int x = rand() % 100 + 1;
        usleep(1234);
        int y = rand() % 100;
        usleep(4321);
        char oper = opers[rand() % opers.size()];
        request req(x, oper, y);
        req.DebugPrint();

        std::string package;
        req.Serialize(&package);

        package = encode(package);

        int n = write(st.Fd(), package.c_str(), package.size());
        std::cout << "这是最新的发出去的请求: " << n << "\n"
                  << package;
        // n = write(st.Fd(), package.c_str(), package.size());
        // std::cout << "这是最新的发出去的请求: \n"
        //           << n << "\n"
        //           << package;
        // n = write(st.Fd(), package.c_str(), package.size());
        // std::cout << "这是最新的发出去的请求: \n"
        //           << n << "\n"
        //           << package;
        // n = write(st.Fd(), package.c_str(), package.size());
        // std::cout << "这是最新的发出去的请求: \n"
        //           << n << "\n"
        //           << package;

        char buffer[128];
        while (true)
        {
            ssize_t read_ret = read(st.Fd(), buffer, sizeof(buffer)); // 我们也无法保证我们能读到一个完整的报文
            if (read_ret > 0)
            {
                buffer[read_ret] = 0;
                inbuffer_stream += buffer; // "len"\n"result code"\n
                // std::cout << inbuffer_stream << std::endl;
                std::string content;
                bool r = decode(inbuffer_stream, &content);
                if(content.empty()) break; 
                // assert(r);
                response resp;
                r = resp.Deserialize(content);
                // assert(r);

                resp.DebugPrint();
            }
            else
            {
                lg(FATAL,"client read error");
                break;
            }
            std::cout << "=================================================" << std::endl;
            sleep(1);
        }
        cnt++;
    }

    st.Close();
    return 0;
    // //测试代码decode
    // request req(1, '+', 2);
    // std::string out;
    // req.Serialize(&out);
    // std::string package = encode(out);
    // std::string content;
    // bool ret = decode(package, &content);
    // std::cout << ret << std::endl;
    // std::cout << content << std::endl;

    // // 测试代码string
    // std::string str1 = "hah";
    // std::string *pstr1 = &str1;
    // std::cout << pstr1->size() << std::endl;
    // std::cout << (*pstr1).size() << std::endl;
    // /* 结果:输出一样 结论：string指针和string对象一样得出是保存字符串的大小*/
}
